﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace zad1
{
    class ComplexNumber
    {
        private double a; // real part
        private double b; // imaginative part

        public ComplexNumber(double realPart, double imaginativePart)
        {
            this.a = realPart;
            this.b = imaginativePart;
        }

        public double RealPart
        {
            get
            {
                return this.a;
            }
        }

        public double ImaginativePart
        {
            get
            {
                return this.b;
            }
        }

        public override string ToString()
        {
            return string.Format("{0} + {1}i", a, b);
        }

        public static ComplexNumber operator +(ComplexNumber c1, ComplexNumber c2)
        {
            double realPart = c1.RealPart + c2.RealPart;
            double imaginativePart = c1.ImaginativePart + c2.ImaginativePart;
            return new ComplexNumber(realPart, imaginativePart);
        }

        public static ComplexNumber operator -(ComplexNumber c1, ComplexNumber c2)
        {
            double realPart = c1.RealPart - c2.RealPart;
            double imaginativePart = c1.ImaginativePart - c2.ImaginativePart;
            return new ComplexNumber(realPart, imaginativePart);
        }

        public static ComplexNumber operator *(ComplexNumber c1, ComplexNumber c2)
        {
            double realPart = c1.RealPart * c2.RealPart - c1.ImaginativePart * c2.ImaginativePart;
            double imaginativePart = c1.ImaginativePart * c2.RealPart + c1.RealPart * c2.ImaginativePart;
            return new ComplexNumber(realPart, imaginativePart);
        }

        public static ComplexNumber operator /(ComplexNumber c1, ComplexNumber c2)
        {
            if(c2.RealPart == 0 && c2.ImaginativePart == 0)
            {
                throw new ArgumentException("Denominator can not be 0!");
            }
            double realPart = (c1.RealPart * c2.RealPart + c1.ImaginativePart * c2.ImaginativePart) / 
                (c2.RealPart * c2.RealPart + c2.ImaginativePart * c2.ImaginativePart);
            double imaginativePart = (c1.ImaginativePart * c2.RealPart - c1.RealPart * c2.ImaginativePart) /
                (c2.RealPart * c2.RealPart + c2.ImaginativePart * c2.ImaginativePart);
            return new ComplexNumber(realPart, imaginativePart);
        }

        public static explicit operator double(ComplexNumber c)
        {
            if (c.ImaginativePart == 0)
            {
                return c.RealPart;
            }
            else
            {
                return double.NaN;
            }
        }

        public static implicit operator ComplexNumber(double num)
        {
            return new ComplexNumber(num, 0);
        }

        public double this[int index]
        {
            get
            {
                if (index == 0)
                {
                    return this.RealPart;
                }
                else if(index == 1)
                {
                    return this.ImaginativePart;
                }
                else
                {
                    throw new ArgumentOutOfRangeException();
                }
            }
        }

    }
    class Program
    {
        static void Main()
        {
            PriorityQueue<int> test = new PriorityQueue<int>();
            test.Add(2);
            test.Add(3);
            test.Add(1);
            test.Add(2);
            test.Add(5);
            for (int i = 0; i < test.Count; i++)
            {
                Console.WriteLine(test[i]);
            }
            Console.WriteLine(test[9]);
        }
    }
}
